'This demo shows how history variables may be used to simulate a physical system evolving through time. In this example, we create a three-segment "snake" of semi-rigid rods. The rods try to keep themselves a constant length.'!
!RodsDemo methodsFor: 'public'!
makeDemo
"RodsDemo new makeDemo"
self buildThing.
self addConstraints.
ThingConstructorView openOn: thing.! !
!RodsDemo methodsFor: 'private'!
addConstraints
"Add force constraints to the new Thing. RodThings already compute the force vector on each endpoints. If the rod is compressed, this force is outward and if the rod is compressed the force is inward. Try changing the constant multiplier of 'force' in these equations to something higher; if it is too high the system will oscillate like a spring, even though we are not modeling mass and momentum, because the difference equations become unstable. Try it!!"
thing methods: #(
'newP _ oldP + (force * 0.3)')
where: #((newP rod1.p1.value)
(oldP rod1.p1.last)
(force rod1.p1Force.last))
strength: #default.
thing methods: #(
'newP _ oldP + (force * 0.3)')
where: #((newP rod3.p2.value)
(oldP rod3.p2.last)
(force rod3.p2Force.last))
strength: #default.
thing methods: #(
'newP _ oldP + ((force1 + force2) * 0.3)')
where: #(
(newP rod2.p2.value)
(oldP rod2.p2.last)
(force1 rod1.p2Force.last)
(force2 rod2.p2Force.last))
strength: #default.
thing methods: #(
'newP _ oldP + ((force1 + force2) * 0.3)')
where: #(
(newP rod2.p1.value)
(oldP rod2.p1.last)
(force1 rod2.p1Force.last)
(force2 rod3.p1Force.last))
strength: #default.!
buildThing
"Build a Thing consisting of three RodThings connected as follows:
"Answer the index of the largest of the leftmost of the first two different keys or zero if all keys from start through stop are identical."
| firstKey |
firstKey _ (array at: start) extent x .
(start + 1) to: stop do:
[: i |
((array at: i) extent x > firstKey)
ifTrue: [^i]
ifFalse:
[((array at: i) extent x < firstKey)
ifTrue: [^start]]].
^0 "all keys are the same"!
insertionSort: aView
| i j bar1 bar2 |
2 to: array size do:
[: i |
j _ i.
[(j > 1) and:
[bar1 _ array at: j.
bar2 _ array at: j - 1.
bar2 extent x > bar1 extent x]] whileTrue:
[self swap: bar1 with: bar2 in: aView.
array at: j put: bar2.
array at: (j - 1) put: bar1.
j _ j - 1]].!
partitionBy: pivotKey from: start to: stop in: aView
"Partition the sub-array from start to stop using the given pivot key. After this operation, all elements whose keys are less than pivotKey will be to the left of those whose keys are the same or equal to pivotKey."
| left right temp |
left _ start.
right _ stop.
[true] whileTrue:
["scan left and right"
[(array at: left) extent x < pivotKey] whileTrue: [left _ left + 1].
[(array at: right) extent x >= pivotKey] whileTrue: [right _ right - 1].
'This demo shows how constraints may be used to handle a simple musical layout problem. Notes are related to each other temporally and their position is related to the time and pitch, within the context of a musical staff.'!
"Note: This demo involves a large number of constraints (126 equality constraints and 256 internal rectangle constraints) so it is somewhat slower than most of the other demos. Because all the constraints are interconnected, the entire constraint graph is traversed when any point is moved with the mouse."
"ChessBoardDemo new makeDemo"
self buildThing.
self addLayoutConstraints.
ThingConstructorView openOn: thing.! !
!ChessBoardDemo methodsFor: 'private'!
addLayoutConstraints
"Add the layout constraints to 'glue' the squares together. While we're at it, make the square colors alternate."
| black previousSquare square |
black _ true.
1 to: 8 do:
[: row |
previousSquare _ nil.
black _ black not.
1 to: 8 do:
[: col |
square _ thing perform:
(('r', row printString, 'c', col printString) asSymbol).
'This example shows how constraints may be used to build the graphical skeleton of a simple table using horizontal and vertical lines and TextThings. Try changing one of the column labels by selecting it and typing (be patient, there are lots of constraints to solve).'!